import { message } from 'antd';
import { config } from './Config';
import { AppendElement } from 'src/app/utils/appendElement';
export class JsonApiService {
  private requestCount: number = 0;
  private appendElement: AppendElement = new AppendElement();
  private time: number;
  public checkPost(url: string, body: object = {}, base: string = 'master', contentType: string = config.contentType, tout: number = config.timeoutNumber): Function  {
    return () => {
      return this.post(url, body, base, contentType, tout);
    }
  }
  public checkGet (url: string, body: object = {}, base: string = 'master', contentType: string = config.contentType, tout: number = config.timeoutNumber): Function {
    return () => {
      return this.get(url, body, base, contentType, tout);
    }
  }
  public post<T>(url: string, body: object = {}, base: string = 'master', contentType: string = config.contentType, tout: number = config.timeoutNumber): Promise<any> {
    this.requestCount++;
    this.appendElement.openLoading(500);
    const Fetch: Promise<Response> = fetch(`${this.getBase(base)}${url}`, {
      method: 'post',
      headers: {
        'Content-Type': contentType,
        'Token': 'xxxxx'
      },
      body: JSON.stringify(body)
    })
    return new Promise((resolve, reject) => {
      this._fetch(Fetch, tout).then((response: Response) => {
        return response.json();
      }).then(responseData => {
        this.status(responseData, resolve);
    }).catch(error => {
        this.status(error, reject);
      });
    })
  }
  public get<T>(url: string, body: object = {}, base: string = 'master', contentType: string = config.contentType, tout: number = config.timeoutNumber): Promise<any> {
    this.requestCount++;
    this.appendElement.openLoading(500);
    const Fetch: Promise<Response> = fetch(`${this.getBase(base)}${url}${this.urlParams(body)}`, {
      method: 'get',
      headers: {
        'Content-Type': contentType,
        'Token': 'xxxxx'
      }
    })
    return new Promise((resolve, reject) => {
      this._fetch(Fetch, tout).then((response: any) => {
        return response.json();
      }).then(responseData => {
        this.status(responseData, resolve);
    }).catch(error => {
        this.status(error, reject);
     });
    })
  }
  private _fetch (requestPromise: Promise<Response>, timeout: number = config.timeoutNumber): Promise<any> {
    let timeoutAction: any = null;
    const timerPromise = new Promise((resolve, reject) => {
      timeoutAction = () => {
        clearTimeout(this.time);
        resolve(new Response(JSON.stringify({code: -405, error: '请求超时', status: 405})));
      }
    })
    this.time = setTimeout(() => {
      timeoutAction();
    }, timeout)
    return Promise.race([requestPromise, timerPromise]);
  }
  private getBase(base: string): string {
    return config.API_URL[base];
  }
  private status(res: any, callback: any): void {
    this.requestCount--;
    switch (res.code) {
      case 1:
        if (res.msg) {
          message.success(res.msg);
        }
        callback(res.data);
        break;
      case -99999:
        message.error(res.error);
      break;
      case -405:
        message.error(res.error);
      break;
      default:
        message.error(res.message);
      break;
    }
    if (this.requestCount < 1) {
      this.appendElement.closeLoading();
    }
  }
  private urlParams(data: object): string | null {
    if (!!!data) {
      return null;
    }
    let paramStr: any = '';
    const paramArr: Array<any> = [];
    const paramsKey: Array<any> = [];
    for (const key in data) {
      paramsKey.push(key);
    }
    paramsKey.sort();
    paramsKey.map((item) => {
      paramArr.push(`${item}=${encodeURIComponent(data[item])}`);
    })
    if (!!paramArr.length) {
      paramStr += `?${paramArr.join('&')}`;
    }
    return paramStr;
  }
}